\chapter{绪论}
\label{cha:intro}

\section{研究背景}
在过去的二十年里，软件在我们的日常生活中无处不在。
每一天，新开发的软件服务为我们带来独特的生活视野，使我们的生活更加便捷与高效。
同时，软件开发为经济发展带来了巨大贡献。
%据非盈利国际软件研究组织Software.org~\cite{software-org}评估，
%软件行业为美国2016年国内生产总值贡献超过1.14万亿美元，
%提供就业岗位超过1050万。
%与过去两年相比，平均增长6.5\%~\cite{2017-eco-report}。
2018年软件和信息技术服务业统计公报指出，
2018年我国软件和信息技术服务业从业人员为643万人，
实现利润总额8079亿元，占GDP比重3.6\%，已成为经济平稳增长的重要推动力量\cite{2018-china-report}。


如此庞大的软件产业建立在不断增长的软件产品基础之上。
因此需要软件开发团队持续快速地研发，以减少每种新产品的上市时间。
例如，通过采用持续部署技术，Facebook公司每天产生的新版本能够达到100次
甚至1000次~\cite{16-icse-continuous}。
与此同时，随着软件需求增加，软件系统越来越复杂。
为能够匹配市场需求的开发速度，
至关重要的一点就是对软件库中组件的重用~\cite{2011-icsr-reuse, 2013-cbse-reuse}。

软件库~\cite{library}是具体语言实现的软件功能模块的集合。
这些库为现代软件提供构建的基础，重用它们可以让开发人员站在巨人的肩膀上，
专注于创新，而不是重塑基本模块。
更具体地说，这些软件库通常提供应用程序编程接口（API）以供开发者来快速构建软件系统。
本文将API简称为接口。


软件开发者在使用这些API时，需要掌握这些接口的功能和约束以正确使用这些编程接口，完成目标任务。
一个接口使用（API usage）是一段使用某个或某些API来完成特定功能的代码片段，
由一些基本程序元素（program element）组成。
例如：目标接口的函数调用，条件判断，算数运算等等。
这些程序元素的组合需要满足目标API的使用约束（usage constraint）。
例如：对目标API参数的检查、API调用顺序关系和异常处理等等。
这些使用约束则和API自身属性相关。
当一个API使用违反了约束中的一个或多个时，我们称为不正确的API使用，即API误用（API misuse）~\cite{16-msr-mubench}。
API误用，已成为导致软件错误、崩溃，
甚至漏洞的重要原因之一~\cite{12-ccs-android,12-ccs-ssl,13-ccs-misuse,13-tosem-missing-call,14-apsys-case,15-icpc-api,16-ase-spec}。
特别地，C语言多应用于操作系统、嵌入式系统、数据库等基础软件中。
因此，对C程序接口误用缺陷研究具有重要价值。
本文将API误用导致的软件错误、崩溃和漏洞，统称为接口误用缺陷，简称为接口缺陷。


图~\ref{fig:1-1-example}展示漏洞CVE-2015-0288~\cite{CVE-2015-0288}的代码片段。
OpenSSL~\cite{openssl}是广泛应用的安全通信软件库。
该库将加密套接字协议层（SSL）~\cite{ssl}中的通信协议和加密算法封装在API中，
以方便客户端开发者使用。
开发者在使用OpenSSL提供的API时，需要对各种证书（certificate）进行验证，
以确保信息的安全性和有效性。
例如，接口\texttt{X509\_get\_pubkey()}用于解码证书，当发生错误时，返回NULL作为错误代码。
因此当开发者忽略对返回值的检查时，则引入一个空指针解引用错误（图中第9行所示）。
攻击者可以通过构造非法的证书，利用该漏洞进行拒绝服务攻击（Denial of Service），
造成目标系统崩溃。



\input{data/code/style}
\input{data/code/cp1-example}


为帮助使用者理解接口的功能和使用约束，
设计人员通过各种方式提供高质量的文档以及应用案例作为参考。
然而在现有的开发环境下，这些辅助材料并不能有效地帮助开发者理解这些使用约束~\cite{09-icse-doc}。
更严重的是，随着开源软件的蓬勃发展，大量的开源软件库没有完整的文档资料，
甚至存在错误的使用说明~\cite{15-ieee-doc-fail, 17-icse-api-doc}。
此外，当遇到API使用问题时，
开发者更喜欢直接在搜索引擎或者问答论坛Stack-Overflow~\cite{stackoverflow}中进行查询，
而不是查看官方使用说明。
不幸的是，这些问答论坛中同样存在大量的错误~\cite{16-sp-stack}。
研究表明，如何正确使用API是阻碍开发者开发的重要瓶颈之一~\cite{16-icse-cry}。


因此，研究人员采用更加主动的方式协助开发者正确使用API，
即软件工程推荐系统（RSSE）~\cite{10-ieee-rsse}。
该方法的核心是在软件工程任务上下文中，
自动获得重要的信息并提供给开发者，以提高开发者的开发效率。
一方面，通过相似代码检索~\cite{05-icse-rec,16-icse-doc-stack,14-msr-stack}提供API使用样例；
或者通过自动补全技术辅助使用者进行开发~\cite{15-tosem-code-cplt}。
另一方面，研究人员通过自动化的分析方法对已有代码进行缺陷检测，
提示潜在的API误用缺陷，以提高代码质量。


在过去的十几年中，
大量的研究成果被成功应用于自动化API缺陷检测~\cite{15-coufless-static-survey,18-icse-saful,survey18}。
特别地，静态分析技术因只需要源代码，可以在开发的早期进行而获得广泛关注~\cite{05-icse-static}。
尽管在API误用检测方面，研究人员投入大量的工作，
API误用在实际项目中依旧普遍存在~\cite{16-ase-spec, 18-icse-stack}。
一项对Google应用商店的调研显示，在11748个安卓应用中，
10327个被测对象（超过88\%）存在至少一个加密相关的API误用~\cite{13-ccs-misuse}。
特别地，富有经验的开发者的代码中~\cite{18-soups-api-blind}，
甚至在对缺陷修复的代码中，同样会出现API误用。
例如，OpenSSL开发者创建缺陷修复补丁（sha: 1c4221）以``修复crl2pkcs7 app中存在的内存泄漏缺陷''。
然而该补丁忽略上下文路径关系，导致在某些可达路径上对``内存重复释放''。
该缺陷被新的补丁（sha: d285b5）修复，修复的日志为``在crl2pl7中避免重复释放缺陷''。


随着软件库接口数量增加、软件规模增长、代码复杂度提高和开源代码广泛应用，
现有的API误用缺陷检测方法面临巨大挑战。
具体来说是检测精度和规模的矛盾关系，
规模则体现在缺陷种类与代码规模两个层面。
一方面，缺陷检测方法需要具有大规模检测能力，即能够应对实际项目需求，
对缺陷进行检测。
同时，支持尽可能多的缺陷类型。
另一方面，缺陷检测方法需要具有较高精度。
如果一个检测工具的结果包含大量误报，即缺陷报告中的缺陷并不是实际缺陷，
使用者将会摒弃这些工具~\cite{10-acm-precision}。
同时，为帮助开发者理解缺陷并提高修复效率，检测结果的有效展示形式也是促进检测工具应用的重要因素之一~\cite{13-icse-donotuse}。
因此，对接口误用静态检测技术研究，以解决实际项目中检测精度和规模的矛盾关系具有重要意义。
如何设计有效的API误用缺陷静态检测技术，
为开发人员提供高精度、低漏报的缺陷检测服务，
并能够辅助开发者理解缺陷、提高修复效率，是目前工业界的迫切需求，
也是学术界的研究热点。


%本章将介绍C程序接口缺陷的概念，总结C程序接口缺陷的关键问题与研究现状，说明研究思路与主要贡献。

%API广泛(18P17)

%什么是API误用(18P27)

%API检测难点(18P25)

\section{研究现状}
针对接口误用缺陷检测，有三大类技术路线：
代码审查、动态检测和静态检测技术。
代码审查技术旨在通过软件同行协同走查代码的方式，人工地找出并修正代码中编码规范错误以及缺陷。
动态检测技术通过执行程序，利用运行时的状态和语义信息检测缺陷。
静态检测技术则不需要执行程序，直接进行缺陷检测。
后文中将通过这三个方面对API误用缺陷检测相关的现有研究进行总结。

\subsection{代码审查}
代码审查（Code Review）是指开发人员通过系统地阅读程序源代码的API使用情况，
以找出并修正程序中错误，从而提升软件质量的活动~\cite{code-review}。
随着版本控制管理工具和开源社区的发展，
在线软件库（例如Github~\cite{github}和Bitbucket~\cite{bitbucket}）可以允许开发者远程协同审查代码，
简化代码审查的代价。
一项调研显示，在对于240个一线开发者的调研中，
超过90\%的开发者所在的公司在使用代码审查技术以提高代码质量~\cite{17-profes-code-review}。
通过开发者协同走查代码，能够有效找到程序中的缺陷、维持代码统一编程风格、增加可维护性、
分享领域知识与协调开发进度~\cite{13-icse-code-review}。
特别地，在2008年对超过12000个实际项目开发流程的调研中，
代码审查的缺陷发现率高达60-65\%~\cite{08-code-review}。

然而，代码审查活动需要大量的人工操作，
是代码开发流程中占用时间最多的活动之一~\cite{13-esem-code-review}。
大量的人力和时间成本使得代码审查受到越来越多的质疑。
其中微软公司2015年的调研结果显示，代码审查严重阻碍开发的进度。
在所有的代码审查结果中，只有15\%的内容与缺陷有关~\cite{15-icse-code-review}。
与此同时，随着代码量的增大，代码审查的效率降低，并需要开发者具备更好的领域知识。
这些因素都制约了代码审查在现代软件开发环境中的效果。


\subsection{动态检测}
动态程序检测技术（Dynamic Program Analysis）是程序分析技术的一种~\cite{15-pa}，
通过程序的运行时行为检测程序的缺陷。
动态程序检测技术利用程序运行时状态或利用运行时捕获的信息，
对程序的内部逻辑以及功能进行缺陷检测。
因此检测结果的正确率可以达到100\%，即没有误报。
针对于接口误用，
典型的动态检测技术是集成测试（Integration Testing）~\cite{17-trustcom-test}。
该方法对已经通过测试的底层API实现模块组合后的代码进行测试，
以检测在组合后API使用代码片段中的误用，
即通过构造输入和输出动态地执行模块以检测程序中API使用的正确性。
近年来，动态验证技术（Runtime Verification）获得广泛的应用~\cite{18-rv}。
动态验证技术从传统的验证技术发展而来，旨在运行时对程序的状态进行监控，以查看程序是否满足预定的属性。
从技术方案上来说，通常需要进行两个步骤：
插桩与日志分析~\cite{07-acm-valgrind, 12-atc-AddressSanitizer}。
插桩通过对源代码或者二进制代码进行语句或者指令的改写，以在运行时输出或者获得程序的状态。
基于获得的程序状态和日志，通过分析技术对程序的运行状态进行查找。
当程序崩溃或者违反预先定义的程序属性时，则找到缺陷。
例如：AddressSanitizer~\cite{12-atc-AddressSanitizer}是由谷歌公司开发针对内存缺陷的检测工具。
该工具已经集成在Clang~\cite{clang}和GCC~\cite{gcc}编译器中，以及Xcode~\cite{Xcode}开发环境中，
找到数百个实际缺陷~\cite{AddressSanitizerFoundBugs}。


动态检测技术具有高精度、跨函数的特点。
能够找到跨越多个函数、复杂的API误用缺陷。
同时，其复杂度与程序的规模呈线性关系，即运行时间不会随着程序规模变化而产生巨大开销。
然而，针对于接口误用缺陷检测，该方法面临以下不足：
（1）程序覆盖率。
动态检测技术对程序的运行时状态进行捕获和分析。
因此，对程序的检测范围取决于测试输入的质量。
模糊测试技术（Fuzzy Testing）~\cite{18-fuzz}通过自动构造随机的输入，
能够有效地增加检测覆盖率，并成功应用于工业界~\cite{18-saner-fuzz}。
然而，在分析过程中依旧只能覆盖程序执行的部分，难以保证所有的程序路径被覆盖。
（2）测试构造与插桩。
一方面，为能够尽可能多地覆盖程序分支，测试人员需要构造大量的测试用例。
然而，这需要大量人力资本和时间，同时需要对程序的语义具有深刻理解。
另一方面插桩技术面对不同的程序结构与编译器的优化策略时，可能失效。
同时，修改后的程序运行效率受到影响。
（3）测试环境。
与针对API实现的测试不同，API使用包含多个程序元素、复杂的逻辑关系以及项目特定的约束条件。
同时，部分API误用缺陷发生在特定的物理环境下~\cite{15-kernel-sv}。
例如：对于特定硬件配置处理的接口，其异常处理需要在特定的环境下才会触发。
这些测试环境的准备需要大量的人力和财力。

\subsection{静态检测}
静态检测技术（Static Program Analysis）~\cite{08-ieee-static}与动态检测技术相对，
在不执行程序的情况下对程序中缺陷进行检测。
针对于接口误用缺陷检测，静态检测技术有三类常用方法：
验证技术、静态分析技术和规约挖掘技术。

\paragraph{验证技术}
程序验证技术通过遍历程序的所有可能状态以证明程序的正确性~\cite{08-tcad-sv}。
针对于接口误用缺陷，程序验证技术本身难以直接对缺陷进行检测，
需要将检测问题转化为可达性问题~\cite{rp}。
检测工具需要提供或内部集成相应API正确使用的约束条件，
并将约束条件与程序状态相对应。
当发现到达违反约束的程序状态时，则认为检测到API误用缺陷。

最具代表的接口误用缺陷验证工具是微软公司的SLAM项目~\cite{slam}。
SLAM项目成立于2001年，旨在检测软件接口使用行为是否满足约束条件，以辅助开发者正确地使用接口的功能。
开发者通过使用SLIC规约描述语言~\cite{01-slic}对程序接口的属性进行描述，
并使用Static Driver Verifier（SDV）~\cite{02-acm-slam}工具对目标API进行检查。
SDV对源代码进行解析并根据SLIC规约对代码进行插桩，
并利用反例引导的抽象解释技术（Counter Example-Guided Abstraction Refinement）
~\cite{00-cav-counter,02-acm-abs}对API误用缺陷进行查找。
至2010年，该项目已经支持200多个API使用规约，
成功检测Windows操作系统驱动程序中270个API误用缺陷，
有效地提高了接口使用的正确性~\cite{10-cad-slam, 11-acm-slam}。
Avinux~\cite{09-avinux}静态验证工具针对操作系统内核，扩展了SLIC描述语言。
该工具对单个预处理的源代码文件进行缺陷检测。
此外，DDVerify~\cite{07-ase-ddverify}针对操作系统的驱动程序进行场景建模，
并对其中的四种场景进行验证。
其他通用验证工具也能够支持部分API误用缺陷类型，例如
CPAchecker~\cite{07-cav-cpachecker}、CBMC~\cite{14-tacas-cbmc}、SMACK~\cite{14-cav-smack}等。


尽管程序验证技术能够支持API误用缺陷检测，但是其面临如下不足：
（1）规约描述语言（Behavior Specification）能够有效地描述接口使用的约束条件。
然而，现有的描述语言多针对接口的功能实现~\cite{blast, acsl}。
虽然SLIC是针对接口使用设计，但是该语言针对于Windows驱动程序设计，
难以应用于普适性的接口误用缺陷检测。
同时该语言使用复杂，需要深刻理解语言以设计相应的规约条件。
（2）尽管验证技术能够实现可靠甚至完备的程序正确性分析，
然而该技术的可延展性难以满足现实开发者的需求。
面对真实项目，状态空间爆炸问题（State Space Explosion Problem）是验证技术难以应用的最重要的挑战之一。

\paragraph{静态分析技术}
静态分析技术与验证技术不同，其目标在于通过强大且灵活可控的抽象方法对大规模软件代码高效分析，
以完成对源代码的缺陷检测。
该技术能够在开发的早期使用，有效地降低缺陷检测和修复的成本~\cite{06-cost}。
因此，近年来静态分析技术成为代码质量保证的有效途径之一，并被广泛使用。
静态分析工具在代码的编译时或基于编译后的中间表达（Intermediate Representation），
利用预先定义好的规则基于程序信息对接口误用缺陷进行检测，
即在程序中是否能够发现某些代码违反了正确的编程规则。
例如，API的参数是否为空指针~\cite{00-osdi-npd}，
Linux内核API是否使用正确~\cite{09-dsn-linux}等等。

近二十年来，研究人员和开发者设计并实现了大量的开源静态分析工具~\cite{wiki-static-tool}。
支持接口误用缺陷检测的代表性工具包括：Clang Static Analyzer（Clang-SA）~\cite{clang-sa}，
Cppcheck~\cite{cppcheck}，Infer~\cite{infer}，Sparse~\cite{sparse}，
Splint~\cite{splint}，SSLINT~\cite{15-sp-sslint}等等。
Clang Static Analyzer（Clang-SA）~\cite{clang-sa}是开源编译器框架LLVM~\cite{llvm}的重要模块之一，
能够独立运行。
该工具利用符号执行技术（Symbolic Execution）~\cite{13-acm-se}推理程序的语义信息，
并通过检测插件（checker）的形式对程序中的缺陷进行检测。
Cppcheck~\cite{cppcheck}工具将代码预处理为符号（token）流，
并在符号流中通过模式匹配的方法进行缺陷检测。
为支持用户自定义的接口，Cppcheck提供一套轻量级的规约描述方法，以供使用者撰写项目特定的接口使用约束。
与上述两种通用缺陷静态分析工具互补，
Facebook公司的Infer工具关注内存安全，
Sparse和Splint工具针对Linux操作系统设计，
SSLINT则通过对SSL协议建模以对安全相关API误用进行缺陷检测。


为能够支持大规模、多领域、快速检测的需求，
静态分析技术一方面将规则编码在分析引擎或者检测插件中，
另一方面采用抽象的方法简化程序结构。
因此针对于大规模复杂的API误用缺陷检测，其面临如下不足：
（1）缺陷模式硬编码，对用户自定义API支持不足。
例如，Clang-SA提供大量的检测插件，然而其无法快速支持用户自定义API，
即该工具缺少轻量级的接口以供使用者开发新的检测器。
虽然Cppcheck提供的规约描述方法能够有效地缓解用户自定义接口缺陷检测困难。
但是其语义简单，难以应对复杂的接口误用缺陷模式。
（2）检测结果难以满足用户实际要求。
为了能够给使用者提供好的用户体验，静态分析工具往往采取保守策略，
即只报告高置信度的缺陷。
因此，大量的实际缺陷被忽略，产生漏报。
如果提高报告率，则产生大量的误报，
即报告的缺陷实际为正确使用。
API使用多包含复杂的上下文语义信息，甚至跨越多层函数调用。
同时，针对不同的路径条件，API使用的约束条件不同。
现有的静态分析工具多基于语法结构进行分析，
忽略路径信息和过程间（inter-procedural）语义信息，
以应对大规模快速分析的需求。
因此，会产生大量的漏报以及误报。
（3）检测结果展示有效性不足。
目前，静态分析工具生成的报告有效信息难以辅助开发者理解缺陷与修复。
为帮助开发者对缺陷进行修复，
提高缺陷检测结果的展示形式是促进检测工具应用的重要因素之一~\cite{13-icse-donotuse}。

\paragraph{规约挖掘技术}
为了弥补传统静态程序分析技术规约撰写困难、难以支持用户自定义接口的不足，
近年来研究人员通过基于数据驱动的挖掘技术来自动推理API使用约束~\cite{13survey}。
这些技术核心思想是在大规模代码库中，出现次数多的使用形式为正确的模式，出现次数少的则为误用。
通俗来说，首先通过挖掘技术学习程序中API使用的约束。
此后，通过这些约束进行异常检测。
随着开源代码库（例如Github）与代码挖掘平台（例如：BOA平台~\cite{15-tosem-boa}）的蓬勃发展，
大量的工作被投入到规约挖掘技术与工具研究中，并成功应用于实际项目中~\cite{survey18}。

基于数据挖掘规约的推理技术，最早由Engler等于2001年提出~\cite{01-sosp-mining}。
该方法通过用户自定义的规则模板，在代码中自动推理API使用约束。
例如，接口\texttt{A}必须与接口\texttt{B}成对出现。
此后，Li等基于频繁项目挖掘技术（Frequent Itemset Mining）~\cite{03-fimi-frequent}，
设计并开发了全自动的规约挖掘工具PR-Miner~\cite{05-fse-prminer}，
有效地提高这类方法的精度，增加支持的缺陷模式种类。
此后，研究人员不断地设计并实现新的推理技术以支持更多的规约模式。
例如，带有条件的因果调用关系（causal relationship）~\cite{07-fse-temporal}，
调用序列~\cite{09-ase-sequence}，接口调用前置条件~\cite{14-fse-pre}，
异常处理~\cite{16-ase-apex}，以及多种API混合使用约束~\cite{16-sec-apisan}等等。
总结来说，这些方法的不同在于如何对源代码进行标准化表示、
如何统计API使用的次数、如何区别上下文关系和如何通过学习的规约条件进行缺陷检测等等。

尽管规约挖掘技术能够自动化学习API使用约束，同时进行误用缺陷检测，
这些方法在实际应用中经常产生大量误报与漏报。其主要原因包括：
（1）难以获得足够的训练数据。
基于数据驱动的学习技术需要大量的有效数据以学习正确的规约条件。
然而在单个项目中，难以满足数据量的需求，
特别是用户自定义的接口~\cite{15-kernel-sv,survey18}。
（2）无关语句影响学习结果。
现有的学习技术多基于语法结构进行分析，缺失的语义信息导致在学习过程中
无关语句对结果影响巨大~\cite{16-icse-antminer}。
（3）无法学习隐式规约条件。
基于学习的方法只能够学习显式的规约条件，而对于C程序无法显式表示的条件则无法学习。
例如：C标准库的\texttt{free()}接口不可以释放非堆内存，不然会导致一个释放非堆内存（CWE-590：free of memory not on the heap）错误。
然而C程序语法中无法描述该属性。

\paragraph{总结}
程序接口误用缺陷检测的三大类技术路线（代码审查、动态检测和静态检测技术）具有各自的特点和不足。
其中，动态检测和静态检测能够实现自动化或者半自动化，目前较为受开发者的欢迎。
动态检测需要执行目标程序，在运行时或基于运行时信息进行缺陷检测。
因此，需要可执行的程序，并且存在覆盖率低和人工构造测试环境困难等不足。
特别地，针对部分误用缺陷模式（例如：异常处理、资源泄漏等）需要特殊环境和大量的时间触发缺陷。
静态分析则可以在开发早期进行，并能够覆盖全部程序，不需要大量人工参与。
但是，存在分析精度、规模等不足。
本文旨在发现实际项目中接口误用缺陷，在开发早期尽可能保证接口正确使用。
因此，本文选择静态分析技术进行研究。



\section{研究思路}

\begin{figure}[t]
	\centering
	\includegraphics[width=0.85\linewidth]{figures/cp1-overview.png}
	\caption{
		论文研究思路
	}
	\label{fig:1-3-overview}
\end{figure}

随着软件规模增长、代码复杂度提高以及开源代码的广泛使用，现有的API误用检测方法面临巨大挑战。
因此，本文旨在提高接口误用缺陷检测能力，以应对实际项目中接口误用检测精度与规模的矛盾关系。
即在大规模实际项目中支持多种接口误用缺陷类型的同时，尽可能地保证检测的精度。
特别地，C语言多应用于操作系统、嵌入式系统、服务器、数据库等基础软件，需要极高的可靠性和安全性。
因此，本文以C语言作为载体。
针对上述已有研究面临的问题，
本文将提出基于静态分析的C程序接口误用缺陷检测技术
和相关的支持工具集合Tsmart-IMChecker。
整体的研究思路如图~\ref{fig:1-3-overview}所示。
本文将从自底向上的3个层次展开研究：表示层、分析层和应用层。
表示层关注接口使用约束的描述，侧重接口使用约束的描述能力。
对API使用约束条件进行描述是接口缺陷检测的重要基础。
因此，该研究对有效检测接口误用缺陷至关重要。
分析层关注接口误用缺陷检测的方法，侧重检测方法对实际程序中规模与准确性的平衡关系。
随着开源社区的发展，现代软件呈现出大规模、复杂化的特点。
因此，高效、准确的检测方法，是提高代码质量的重要方法。
应用层关注接口误用缺陷检测方法在实际项目中的应用效果，
侧重接口误用测试数据集整理和工具在实际中的应用效果。
本文将总结C程序接口误用缺陷数据集，
开发可视化支撑接口误用缺陷检测工具集。
并将工具在开源项目应用的经验进行总结，
以帮助研究人员和开发人员更好地理解接口误用缺陷。

本文的具体研究思路如下：
\begin{enumerate}
	\item {\kaishu 基于缺陷模式的接口使用约束描述。}
	规约描述语言能够有效地定义API使用的约束条件。
	然而当前已有规约描述语言多关注于接口的实现或特定应用场景。
	自动规约挖掘技术则面临有效数据集缺失的问题，难以支持实际项目中接口误用缺陷的特性。
	因此本文选择接口误用缺陷模式作为切入点，设计一套轻量级的接口使用约束领域特定语言。
	（1）为理解C程序接口误用缺陷的常见模式，本文将对不同领域的开源项目中的实际接口缺陷报告进行调研，
	总结常见接口误用缺陷模式。
	（2）针对C程序接口误用缺陷的常见模式，设计一套面向C程序接口使用约束的领域特定语言。
	该语言应支持多种接口使用约束模式的描述，同时易扩展到新的接口缺陷类型。
	本部分重点研究接口使用约束描述的表达能力，是本文研究的重要基础。
	
	\item {\kaishu 规模化接口误用缺陷检测技术。}
	现代软件具有规模大、结构复杂的特点。
	因此，静态分析的分析效率（大规模程序）与检测准确性（误报率和漏报率）难以同时满足。
	针对两者平衡这一关键问题，面向接口误用缺陷的特点，本文关注如何对静态分析任务进行分而治之，
	以缓解分析过程中路径、状态爆炸等问题。
	同时，在支持大规模代码分析的同时，做到对局部代码的精确分析。
	（1）针对大规模目标程序，本文将采用多入口分析策略，提取和接口缺陷相关的抽象符号路径语义信息，
	并设计基于约束描述的接口缺陷检测算法，以支持用户自定义的接口。
	（2）为降低多入口分析带来的精度损失，本文将通过基于上下文的语义信息和基于使用情况的的统计信息，
	对检测结果进行过滤与排序，以提高检测的精度。
	本部分重点研究检测方法对分析效率和准确性平衡关系，是本文研究的核心技术方法。
	
	\item {\kaishu 接口误用缺陷检测应用。}
	为帮助研究人员更好地理解C程序接口误用缺陷，满足开发者的使用需求，
	本文将提供C程序接口误用缺陷数据集APIMU4C与C程序接口误用缺陷检测工具集Tsmart-IMChecker。
	（1）为帮助研究人员与开发者更好地理解C程序接口误用缺陷，
	本文将对接口误用缺陷模式调研中的实例进行总结。
	同时，为更好地评估现有接口缺陷检测工具的能力与引导新的检测技术的开发，
	本文将结合现有测试数据集与接口误用缺陷模式，构造针对C程序的接口误用测试数据集。
	（2）
	如何降低用户的使用代价和提供有效的缺陷展示功能以辅助开发者理解缺陷是使用者对静态分析工具的迫切需求。
	因此，为提高检测工具的用户友好性以及辅助使用者理解缺陷检测结果，
	本文将开发一系列可视化的工具来辅助开发者进行接口使用约束的撰写、缺陷检测和结果分析。
	（3）
	最后，本文将在开源项目中进行工具集的案例应用，并总结应用的结果和经验。
	本部分重点研究针对C程序接口误用缺陷的数据集以及工具应用，是本文方法的实际应用。
\end{enumerate}




\section{论文贡献}
本文根据上述研究思路，针对C程序接口误用缺陷的静态检测技术进行系统性研究，取得相应的理论效果，
实现了对应的工具集合~\cite{19-icse-imchecker, 19-tase-imspec, 19-compsac-empirical}。论文的具体贡献如下：

\begin{enumerate}
	\item 提出用于描述C程序接口使用约束的领域特定语言以及规模化接口误用缺陷检测方法。
	首先，为理解C程序接口误用缺陷的特点，
	本文对不同领域、广泛应用的六个开源项目中830个实际API误用缺陷修复报告进行调研，
	共总结出三大类常见接口误用缺陷模式。
	%据作者所知，这是第一个针对C程序接口误用缺陷的调研工作。
	基于缺陷模式，本文设计C程序接口使用约束的领域特定语言IMSpec，
	并与传统自然语言描述方式对比。
	实验结果表明，IMSpec能够有效描述多种接口使用约束，
	帮助开发者多找到12.5\%的误用缺陷实例。
	同时本文设计并实现基于约束描述的规模化接口误用缺陷检测方法。
	该方法利用多入口分析策略、抽象路径提取和基于程序语义和使用情况的过滤排序技术，
	将规模化代码分析任务分而治之，达到高效率分析的同时，实现局部的精确分析。
	本文选择Juliet Test Suite~\cite{juliet}中13个接口缺陷相关CWE分类的共2172个程序进行评估。
	结果表明，本文提出的方法误报率和漏报率分别为13.21\%和16.80\%，
	优于主流的开源静态分析工具。
	
	\item 总结C程序接口误用缺陷数据集并开发基于图形化的检测工具集。
	基于开源项目和公开测试数据集，本文提供C程序接口误用缺陷数据集APIMU4C。
	据作者所知，这是第一个针对C程序接口误用缺陷的数据集。
	APIMU4C数据集能够帮助研究人员和开发者理解C程序接口缺陷，以及评估工具的缺陷检测能力。
	同时本文设计并实现可视化支撑的C程序接口误用缺陷检测工具集。
	在工具集中，本文集成规约撰写工具IMSpec-writer、接口缺陷分析引擎IMChecker-engine
	和基于差异性对比的结果展示工具IMDisplayer，以辅助开发者撰写IMSpec约束文件和理解缺陷检测结果。
	本文将Tsmart-IMChecker工具集应用于广受关注的开源软件中，
	在Linux内核、OpenSSL库以及Ubuntu操作系统中找到112个新的接口误用缺陷。
	至今，在75个提交的缺陷报告中，61个缺陷被开发者确认，其中32个已经被开发者在主分支修复。
	本文对实际应用 结果和经验进行总结，供研究人员和开发人员参考。
	
	
	
\end{enumerate}
\section{论文结构}
本文共包括5个章节。第2章介绍针对接口使用约束的领域特定语言，
包括基于实际案例的接口误用缺陷模式以及领域特定语言的设计思路、语法和语义。
第3章讨论规模化接口误用缺陷静态检测方法。
第4章对接口误用缺陷数据集和检测工具集进行介绍，并对工具集在开源项目的应用结果进行总结。
最后，第5章总结全文并展望延伸本文工作的若干方向。
